package handler

import (
	"account-service/models"
	"account-service/tools"
	"context"
	"math"
	"strconv"
	"strings"
	"time"

	pbAccount "account-service/proto/account"
	pbParams "account-service/proto/params"
	pbResult "account-service/proto/result"
	pbRole "account-service/proto/role"

	"google.golang.org/grpc/codes"
	"google.golang.org/grpc/status"
)

/*
 +----------------------------------------------------------------------
 + Title        : AccountHandler
 + Author       : huwl
 + Version      : 1.0.0
 + Initial-Time : 2019-08-08
 + Last-time    : 这个文件最后修改的时间 + 修改人的名称
 + Desc         : 账户处理
 +----------------------------------------------------------------------
*/

type AccountHandler struct {
	pbAccount.UnimplementedAccountSrvServer
}

/**
 * 新增账户
 *
 * @param string Username ---------------------------------必传,用户名
 * @param string Password ---------------------------------必传,密码
 * @param string Name -------------------------------------非必传,姓名
 * @param string Mobile -----------------------------------必传,手机号
 * @param string Title ------------------------------------非必传,职位
 * @param string Email ------------------------------------必传,邮箱
 * @param string Avatar -----------------------------------非必传,头像
 * @param int32 IsCash ------------------------------------非必传,是否提现
 * @param string Note -------------------------------------非必传,备注
 * @return *pbResult.Result, error
 * @author huwl
 */
func (e *AccountHandler) AddAcount(ctx context.Context, req *pbAccount.AddAcountRequest) (*pbResult.Result, error) {
	if req.Username == "" {
		return nil, status.Errorf(codes.InvalidArgument, "请输入用户名")
	}
	if req.Password == "" {
		return nil, status.Errorf(codes.InvalidArgument, "请输入密码")
	}
	if !tools.CheckMobile(req.Mobile) {
		return nil, status.Errorf(codes.InvalidArgument, "请输入格式正确的手机号")
	}
	if !tools.CheckEmail(req.Email) {
		return nil, status.Errorf(codes.InvalidArgument, "请输入格式正确的邮箱")
	}

	//判断账户名是否存在【唯一性】
	var total int64
	err := models.Account{}.GetTotalByParams(&models.Account{}, &total, map[string]interface{}{
		"username":    req.Username,
		"status <> ?": -2,
	})
	if err != nil {
		return nil, status.Errorf(codes.Aborted, err.Error())
	}
	if total > 0 {
		return nil, status.Errorf(codes.Aborted, "账户名已经存在")
	}

	bcryptPassword, _ := tools.Bcrypt(req.Password)
	i, err := models.Account{}.Add(&models.Account{
		Username: req.Username,
		Password: bcryptPassword,
		Name:     req.Name,
		Mobile:   req.Mobile,
		Title:    req.Title,
		Email:    req.Email,
		Avatar:   req.Avatar,
		IsCash:   int8(req.IsCash),
		Note:     req.Note,
		Status:   1,
	})
	if err != nil {
		return nil, status.Errorf(codes.Aborted, err.Error())
	}
	if i <= 0 {
		return nil, status.Errorf(codes.Aborted, "新增账户失败")
	}

	return &pbResult.Result{Code: 200, Msg: "新增账户成功"}, nil
}

/**
 * 删除账户
 *
 * @param string Ids --------------------------------------必传,账户ID,支持多个
 * @return *pbResult.Result, error
 * @author huwl
 */
func (e *AccountHandler) DeleteAcount(ctx context.Context, req *pbParams.IdsRequest) (*pbResult.Result, error) {
	ids := req.Ids
	if ids == "" {
		return nil, status.Errorf(codes.InvalidArgument, "账户ID错误")
	}

	accountIds := strings.Split(strings.TrimRight(ids, ","), ",")
	result, err := models.Account{}.EditByParams(&models.Account{}, map[string]interface{}{"status": -2, "update_time": time.Now()}, map[string]interface{}{"id IN (?)": accountIds})
	if err != nil {
		return nil, status.Errorf(codes.Aborted, err.Error())
	}
	if result <= 0 {
		return nil, status.Errorf(codes.Aborted, "删除账户失败")
	}

	return &pbResult.Result{Code: 200, Msg: "删除账户成功"}, nil
}

/**
 * 编辑账户
 *
 * @param int Id ------------------------------------------必传,账户ID
 * @param string Username ---------------------------------非必传,用户名
 * @param string Name -------------------------------------非必传,姓名
 * @param string Mobile -----------------------------------非必传,手机号
 * @param string Title ------------------------------------非必传,职位
 * @param string Email ------------------------------------非必传,邮箱
 * @param string Avatar -----------------------------------非必传,头像
 * @param int32 IsCash ------------------------------------非必传,是否提现
 * @param string Note -------------------------------------非必传,备注
 * @return *pbResult.Result, error
 * @author huwl
 */
func (e *AccountHandler) EditAcount(ctx context.Context, req *pbAccount.EditAcountRequest) (*pbResult.Result, error) {
	if req.Id <= 0 {
		return nil, status.Errorf(codes.InvalidArgument, "账户ID错误")
	}

	params := map[string]interface{}{
		"update_time": time.Now(),
	}
	if req.Username != "" {
		params["username"] = req.Username
	}
	if req.Name != "" {
		params["name"] = req.Name
	}
	if req.Mobile != "" {
		params["mobile"] = req.Mobile
	}
	if req.Title != "" {
		params["title"] = req.Title
	}
	if req.Email != "" {
		params["email"] = req.Email
	}
	if req.Avatar != "" {
		params["avatar"] = req.Avatar
	}
	if req.IsCash != 0 {
		if req.IsCash == -1 {
			params["is_cash"] = 0
		} else {
			params["is_cash"] = req.IsCash
		}
	}
	if req.Note != "" {
		params["note"] = req.Note
	}

	//判断账户名是否存在【唯一性】
	if req.Username != "" {
		var total int64
		err := models.Account{}.GetTotalByParams(&models.Account{}, &total, map[string]interface{}{
			"username":    req.Username,
			"status <> ?": -2,
			"id <> ?":     req.Id,
		})
		if err != nil {
			return nil, status.Errorf(codes.Aborted, err.Error())
		}
		if total > 0 {
			return nil, status.Errorf(codes.Aborted, "账户名已经存在")
		}
	}

	//编辑
	i, err := models.Account{}.EditByPrimaryKey(&models.Account{}, params, req.Id)
	if err != nil {
		return nil, status.Errorf(codes.Aborted, err.Error())
	}
	if i <= 0 {
		return nil, status.Errorf(codes.Aborted, "编辑账户失败")
	}

	return &pbResult.Result{Code: 200, Msg: "编辑账户成功"}, nil
}

/**
 * 编辑账户状态
 *
 * @param string Ids --------------------------------------必传,账户ID
 * @param int32 Status ------------------------------------必传,账户ID
 * @return *pbResult.Result, error
 * @author huwl
 */
func (e *AccountHandler) EditAcountStatus(ctx context.Context, req *pbParams.EditStatusRequest) (*pbResult.Result, error) {
	if req.Ids == "" {
		return nil, status.Errorf(codes.InvalidArgument, "账户ID错误")
	}
	if tools.IsContainNumber([]int{-1, 1}, int(req.Status)) {
		return nil, status.Errorf(codes.InvalidArgument, "账户状态错误")
	}

	accountIds := strings.Split(strings.TrimRight(req.Ids, ","), ",")

	result, err := models.Account{}.EditByParams(&models.Account{}, map[string]interface{}{
		"status":      req.Status,
		"update_time": time.Now(),
	}, map[string]interface{}{"id IN (?)": accountIds})
	if err != nil {
		return nil, status.Errorf(codes.Aborted, err.Error())
	}

	message := ""
	if req.Status == 1 {
		message = "启用账户"
	} else {
		message = "禁用账户"
	}
	if result <= 0 {
		return nil, status.Errorf(codes.Aborted, message+"失败")
	}

	return &pbResult.Result{Code: 200, Msg: message + "成功"}, nil
}

/**
 * 账户详情
 *
 * @param uint64 Id ---------------------------------------必传,账户ID
 * @return *pbAccount.AccountDetailResponse, error
 * @author huwl
 */
func (e *AccountHandler) AccountDetail(ctx context.Context, req *pbParams.DetailRequest) (*pbAccount.AccountDetailResponse, error) {
	if req.Id <= 0 {
		return nil, status.Errorf(codes.InvalidArgument, "账户ID错误")
	}

	//获取账户信息
	account := models.Account{}
	result, err := models.Account{}.GetResultByPrimaryKey(&account, req.Id)
	if err != nil {
		return nil, status.Errorf(codes.Aborted, err.Error())
	}
	if result <= 0 || account.Status == -2 {
		return nil, status.Errorf(codes.Aborted, "账户信息错误")
	}

	//获取账户与角色关联信息
	accountRoles := []models.AccountRole{}
	err = models.AccountRole{}.GetResultsByParams(&models.AccountRole{}, &accountRoles, map[string]interface{}{
		"account_id": req.Id,
	}, 1, -1, "id desc")
	if err != nil {
		return nil, status.Errorf(codes.Aborted, err.Error())
	}

	//获取账户角色
	roleIds := []interface{}{}
	for _, accountRole := range accountRoles {
		roleIds = append(roleIds, accountRole.RoleId)
	}

	roleItems := []models.Role{}
	err = models.Role{}.Rows(&roleItems, roleIds)
	if err != nil {
		return nil, status.Errorf(codes.Aborted, err.Error())
	}

	// 组装角色数据
	roles := []*pbRole.Role{}
	for _, roleItem := range roleItems {
		roles = append(roles, &pbRole.Role{
			Id:         uint32(roleItem.Id),
			Name:       roleItem.Name,
			IsAdmin:    int32(roleItem.IsAdmin),
			Note:       roleItem.Note,
			CreateTime: roleItem.CreateTime.Format("2006-01-02 15:04:05"),
			UpdateTime: roleItem.UpdateTime.Format("2006-01-02 15:04:05"),
		})
	}

	//获取角色与权限关联数据
	roleAuthes := []models.RoleAuth{}
	err = models.RoleAuth{}.GetResultsByParams(&models.RoleAuth{}, &roleAuthes, map[string]interface{}{
		"role_id IN (?)": roleIds,
	}, 1, -1, "id desc")
	if err != nil {
		return nil, status.Errorf(codes.Aborted, err.Error())
	}

	authIds := []interface{}{}
	for _, roleAuth := range roleAuthes {
		authIds = append(authIds, roleAuth.AuthId)
	}

	//获取权限数据
	authItems := []models.Auth{}
	err = models.Auth{}.Rows(&authItems, authIds)
	if err != nil {
		return nil, status.Errorf(codes.Aborted, err.Error())
	}

	// 组装权限数据
	authes := []*pbAccount.Permission{}
	for _, auth := range authItems {
		authes = append(authes, &pbAccount.Permission{
			Name:           auth.Name,
			ControllerName: auth.ControllerName,
			ActionName:     auth.ActionName,
			IsMenu:         int32(auth.IsMenu),
		})
	}

	return &pbAccount.AccountDetailResponse{
		Account: &pbAccount.Account{
			Id:             uint32(account.Id),
			Username:       account.Username,
			Name:           account.Name,
			Password:       account.Password,
			Mobile:         account.Mobile,
			Title:          account.Title,
			Email:          account.Email,
			Avatar:         account.Avatar,
			IsCash:         uint32(account.IsCash),
			CreatePersonId: uint32(account.CreatePersonId),
			VerifyStaffId:  uint32(account.VerifyStaffId),
			VerifyTime:     account.VerifyTime.Format("2006-01-02 15:04:05"),
			Note:           account.Note,
			Status:         int32(account.Status),
			CreateTime:     account.CreateTime.Format("2006-01-02 15:04:05"),
			UpdateTime:     account.UpdateTime.Format("2006-01-02 15:04:05"),
		},
		Roles:  roles,
		Authes: authes,
	}, nil
}

/**
 * 获取单条账户数据
 *
 * @param string Username ---------------------------------非必传,用户名
 * @param string Name -------------------------------------非必传,姓名
 * @param string Mobile -----------------------------------非必传,手机号
 * @param string Title ------------------------------------非必传,职位
 * @param string Email ------------------------------------非必传,邮箱
 * @param string IsCash -----------------------------------非必传,是否允许提现
 * @param string Status -----------------------------------非必传,状态
 * @return *pbAccount.AccountDetailResponse, error
 * @author huwl
 */
func (e *AccountHandler) Row(ctx context.Context, req *pbAccount.QueryAccountRequest) (*pbAccount.AccountDetailResponse, error) {
	params := map[string]interface{}{}
	if req.Username != "" {
		params["username"] = req.Username
	}
	if req.Name != "" {
		params["name"] = req.Name
	}
	if req.Mobile != "" {
		params["mobile"] = req.Mobile
	}
	if req.Title != "" {
		params["title"] = req.Title
	}
	if req.Email != "" {
		params["email"] = req.Email
	}
	if req.IsCash != "all" {
		params["is_cash"] = req.IsCash
	}
	if req.Status != "all" {
		params["status"] = req.Status
	}

	// 获取账户信息
	account := models.Account{}
	i, err := models.Account{}.Row(&models.Account{}, &account, params)
	if err != nil {
		return nil, status.Errorf(codes.Aborted, err.Error())
	}
	if i <= 0 || account.Status == -2 {
		return nil, status.Errorf(codes.Aborted, "账户信息错误")
	}

	// 获取账户与角色关联信息
	accountRoles := []models.AccountRole{}
	err = models.AccountRole{}.GetResultsByParams(&models.AccountRole{}, &accountRoles, map[string]interface{}{
		"account_id": account.Id,
	}, 1, -1, "id desc")
	if err != nil {
		return nil, status.Errorf(codes.Aborted, err.Error())
	}

	// 获取账户角色
	roleIds := []interface{}{}
	for _, accountRole := range accountRoles {
		roleIds = append(roleIds, accountRole.RoleId)
	}

	roleItems := []models.Role{}
	err = models.Role{}.Rows(&roleItems, roleIds)
	if err != nil {
		return nil, status.Errorf(codes.Aborted, err.Error())
	}

	// 组装角色数据
	roles := []*pbRole.Role{}
	for _, roleItem := range roleItems {
		roles = append(roles, &pbRole.Role{
			Id:         uint32(roleItem.Id),
			Name:       roleItem.Name,
			IsAdmin:    int32(roleItem.IsAdmin),
			Note:       roleItem.Note,
			CreateTime: roleItem.CreateTime.Format("2006-01-02 15:04:05"),
			UpdateTime: roleItem.UpdateTime.Format("2006-01-02 15:04:05"),
		})
	}

	// 获取角色与权限关联数据
	roleAuthes := []models.RoleAuth{}
	err = models.RoleAuth{}.GetResultsByParams(&models.RoleAuth{}, &roleAuthes, map[string]interface{}{
		"role_id IN (?)": roleIds,
	}, 1, -1, "id desc")
	if err != nil {
		return nil, status.Errorf(codes.Aborted, err.Error())
	}

	authIds := []interface{}{}
	for _, roleAuth := range roleAuthes {
		authIds = append(authIds, roleAuth.AuthId)
	}

	// 获取权限数据
	authItems := []models.Auth{}
	err = models.Auth{}.Rows(&authItems, authIds)
	if err != nil {
		return nil, status.Errorf(codes.Aborted, err.Error())
	}

	// 组装权限数据
	authes := []*pbAccount.Permission{}
	for _, auth := range authItems {
		authes = append(authes, &pbAccount.Permission{
			Name:           auth.Name,
			ControllerName: auth.ControllerName,
			ActionName:     auth.ActionName,
			IsMenu:         int32(auth.IsMenu),
		})
	}

	return &pbAccount.AccountDetailResponse{
		Account: &pbAccount.Account{
			Id:             uint32(account.Id),
			Username:       account.Username,
			Name:           account.Name,
			Password:       account.Password,
			Mobile:         account.Mobile,
			Title:          account.Title,
			Email:          account.Email,
			Avatar:         account.Avatar,
			IsCash:         uint32(account.IsCash),
			CreatePersonId: uint32(account.CreatePersonId),
			VerifyStaffId:  uint32(account.VerifyStaffId),
			VerifyTime:     account.VerifyTime.Format("2006-01-02 15:04:05"),
			Note:           account.Note,
			Status:         int32(account.Status),
			CreateTime:     account.CreateTime.Format("2006-01-02 15:04:05"),
			UpdateTime:     account.UpdateTime.Format("2006-01-02 15:04:05"),
		},
		Roles:  roles,
		Authes: authes,
	}, nil
}

/**
 * 账户列表
 *
 * @param uint32 Id ---------------------------------------非必传,账户ID
 * @param string Ids --------------------------------------非必传,账户ID,支持多个
 * @param string Username ---------------------------------非必传,用户名
 * @param string Name -------------------------------------非必传,姓名
 * @param string Mobile -----------------------------------非必传,手机号
 * @param string Title ------------------------------------非必传,职位
 * @param string Email ------------------------------------非必传,邮箱
 * @param string IsCash -----------------------------------非必传,是否允许提现
 * @param string Status -----------------------------------非必传,状态支持多个：1,-1
 * @param string StartCreateTime --------------------------非必传,开始创建时间
 * @param string EndCreateTime ----------------------------非必传,结束创建时间
 * @param string SortType ---------------------------------非必传,排序方式
 * @param string SortField --------------------------------非必传,排序字段
 * @param uint32 PageSize ---------------------------------非必传,条数
 * @param uint32 Page -------------------------------------非必传,页码
 * @return *pbAccount.AccountListResponse, error
 * @author huwl
 */
func (e *AccountHandler) AccountList(ctx context.Context, req *pbAccount.QueryAccountRequest) (*pbAccount.AccountListResponse, error) {
	params := map[string]interface{}{
		"status <> ?": -2,
	}
	if req.Id > 0 {
		params["id"] = req.Id
	}
	if req.Ids != "" {
		params["id in (?)"] = tools.IntSplit(req.Ids, ",")
	}
	if req.Username != "" {
		params["username"] = req.Username
	}
	if req.Name != "" {
		params["name"] = req.Name
	}
	if req.Mobile != "" {
		params["mobile"] = req.Mobile
	}
	if req.Title != "" {
		params["title"] = req.Title
	}
	if req.Email != "" {
		params["email"] = req.Email
	}
	if req.IsCash != "all" {
		params["is_cash"] = req.IsCash
	}
	if req.Status != "all" {
		params["status in (?)"] = tools.IntSplit(req.Status, ",")
	}
	if req.StartCreateTime != "" {
		params["create_time >= ?"] = req.StartCreateTime + " 00:00:00"
	}
	if req.EndCreateTime != "" {
		params["create_time <= ?"] = req.EndCreateTime + " 23:59:59"
	}
	if req.SortField == "" {
		req.SortField = "id"
	}
	if req.SortType == "" {
		req.SortType = "desc"
	}
	if req.PageSize == 0 {
		req.PageSize = 20
	}
	if req.Page == 0 {
		req.Page = 1
	}

	//获取账户数量
	var total int64
	err := models.Account{}.GetTotalByParams(&models.Account{}, &total, params)
	if err != nil {
		return nil, status.Errorf(codes.Aborted, err.Error())
	}

	//获取账户数据
	accounts := []models.Account{}
	if total > 0 {
		err = models.Account{}.GetResultsByParams(&models.Account{}, &accounts, params, int(req.Page), int(req.PageSize), req.SortField+" "+req.SortType)
		if err != nil {
			return nil, status.Errorf(codes.Aborted, err.Error())
		}
	}

	//组装账户数据
	accountItems := []*pbAccount.Account{}
	for _, account := range accounts {
		accountItems = append(accountItems, &pbAccount.Account{
			Id:             uint32(account.Id),
			Username:       account.Username,
			Name:           account.Name,
			Password:       account.Password,
			Mobile:         account.Mobile,
			Title:          account.Title,
			Email:          account.Email,
			Avatar:         account.Avatar,
			IsCash:         uint32(account.IsCash),
			CreatePersonId: uint32(account.CreatePersonId),
			VerifyStaffId:  uint32(account.VerifyStaffId),
			VerifyTime:     account.VerifyTime.Format("2006-01-02 15:04:05"),
			Note:           account.Note,
			Status:         int32(account.Status),
			CreateTime:     account.CreateTime.Format("2006-01-02 15:04:05"),
			UpdateTime:     account.UpdateTime.Format("2006-01-02 15:04:05"),
		})
	}

	pageTotal := math.Ceil(float64(total) / float64(req.PageSize))
	return &pbAccount.AccountListResponse{
		Accounts: accountItems,
		ListResult: &pbResult.ListCommonResult{
			Page:      req.Page,
			PageSize:  req.PageSize,
			PageTotal: uint32(pageTotal),
			Total:     uint32(total),
		},
	}, nil
}

/**
 * 账户数量
 *
 * @param uint32 Id ---------------------------------------非必传,账户ID
 * @param string Ids --------------------------------------非必传,账户ID,支持多个
 * @param string Username ---------------------------------非必传,用户名
 * @param string Name -------------------------------------非必传,姓名
 * @param string Mobile -----------------------------------非必传,手机号
 * @param string Title ------------------------------------非必传,职位
 * @param string Email ------------------------------------非必传,邮箱
 * @param string IsCash -----------------------------------非必传,是否允许提现
 * @param string Status -----------------------------------非必传,状态支持多个：1,-1
 * @param string StartCreateTime --------------------------非必传,开始创建时间
 * @param string EndCreateTime ----------------------------非必传,结束创建时间
 * @return *pbResult.TotalResult, error
 * @author huwl
 */
func (e *AccountHandler) AccountTotal(ctx context.Context, req *pbAccount.QueryAccountRequest) (*pbResult.TotalResult, error) {
	params := map[string]interface{}{
		"status <> ?": -2,
	}
	if req.Id > 0 {
		params["id"] = req.Id
	}
	if req.Ids != "" {
		params["id in (?)"] = tools.IntSplit(req.Ids, ",")
	}
	if req.Username != "" {
		params["username"] = req.Username
	}
	if req.Name != "" {
		params["name"] = req.Name
	}
	if req.Mobile != "" {
		params["mobile"] = req.Mobile
	}
	if req.Title != "" {
		params["title"] = req.Title
	}
	if req.Email != "" {
		params["email"] = req.Email
	}
	if req.IsCash != "all" {
		params["is_cash"] = req.IsCash
	}
	if req.Status != "all" {
		params["status in (?)"] = tools.IntSplit(req.Status, ",")
	}
	if req.StartCreateTime != "" {
		params["create_time >= ?"] = req.StartCreateTime + " 00:00:00"
	}
	if req.EndCreateTime != "" {
		params["create_time <= ?"] = req.EndCreateTime + " 23:59:59"
	}

	//获取账户数量
	var total int64
	err := models.Account{}.GetTotalByParams(&models.Account{}, &total, params)
	if err != nil {
		return nil, status.Errorf(codes.Aborted, err.Error())
	}

	return &pbResult.TotalResult{Total: uint32(total)}, nil
}

/**
 * 修改账户密码
 *
 * @param uint32 Id ---------------------------------------必传,账户ID
 * @param string NewPassword ------------------------------必传,新密码
 * @param string PasswordConfirmation ---------------------必传,确认密码
 * @return *pbResult.Result, error
 * @author huwl
 */
func (e *AccountHandler) ChangePassword(ctx context.Context, req *pbAccount.ChangePasswordRequest) (*pbResult.Result, error) {
	if req.Id <= 0 {
		return nil, status.Errorf(codes.InvalidArgument, "账户ID错误")
	}
	if req.NewPassword == "" {
		return nil, status.Errorf(codes.InvalidArgument, "新密码不能为空")
	}
	if req.NewPassword != req.PasswordConfirmation {
		return nil, status.Errorf(codes.InvalidArgument, "确认密码与密码不一致")
	}

	bcryptPassword, _ := tools.Bcrypt(req.NewPassword)
	i, err := models.Account{}.EditByPrimaryKey(&models.Account{}, map[string]interface{}{
		"password":    bcryptPassword,
		"update_time": time.Now(),
	}, req.Id)
	if err != nil {
		return nil, status.Errorf(codes.Aborted, err.Error())
	}
	if i <= 0 {
		return nil, status.Errorf(codes.Aborted, "修改密码失败")
	}

	return &pbResult.Result{Code: 200, Msg: "修改密码成功"}, nil
}

/**
 * 分配角色
 *
 * @param uint32 AccountId --------------------------------必传,账户ID
 * @param string RoleIds ----------------------------------必传,角色ID,支持多个
 * @return *pbResult.Result, error
 * @author huwl
 */
func (e *AccountHandler) AssignRole(ctx context.Context, req *pbAccount.AssignRoleRequest) (*pbResult.Result, error) {
	if req.AccountId <= 0 {
		return nil, status.Errorf(codes.InvalidArgument, "账户ID错误")
	}
	if req.RoleIds == "" {
		return nil, status.Errorf(codes.InvalidArgument, "角色ID错误")
	}

	roleItemIds := strings.Split(req.RoleIds, ",")
	accountRoles := []models.AccountRole{}
	for _, value := range roleItemIds {
		roleId, _ := strconv.Atoi(value)
		accountRoles = append(accountRoles, models.AccountRole{
			AccountId: uint16(req.AccountId),
			RoleId:    uint16(roleId),
		})
	}

	i, err := models.AccountRole{}.Add(&accountRoles)
	if err != nil {
		return nil, status.Errorf(codes.Aborted, err.Error())
	}
	if i <= 0 {
		return nil, status.Errorf(codes.Aborted, "分配角色失败")
	}

	return &pbResult.Result{Code: 200, Msg: "分配角色成功"}, nil
}

/**
 * 取消角色
 *
 * @param uint32 AccountId --------------------------------必传,账户ID
 * @param string RoleIds ----------------------------------必传,角色ID,支持多个
 * @return *pbResult.Result, error
 * @author huwl
 */
func (e *AccountHandler) UnassignRole(ctx context.Context, req *pbAccount.UnassignRoleRequest) (*pbResult.Result, error) {
	if req.AccountId <= 0 {
		return nil, status.Errorf(codes.InvalidArgument, "账户ID错误")
	}
	if req.RoleIds == "" {
		return nil, status.Errorf(codes.InvalidArgument, "角色ID错误")
	}

	roleItemIds := strings.Split(req.RoleIds, ",")
	i, err := models.AccountRole{}.DeleteByParams(&models.AccountRole{}, map[string]interface{}{
		"account_id":     req.AccountId,
		"role_id in (?)": roleItemIds,
	})
	if err != nil {
		return nil, status.Errorf(codes.Aborted, err.Error())
	}
	if i <= 0 {
		return nil, status.Errorf(codes.Aborted, "取消角色失败")
	}

	return &pbResult.Result{Code: 200, Msg: "取消角色成功"}, nil
}

/**
 * 账户与角色关联信息
 *
 * @param uint32 Id ------------------------------------------非必传,ID
 * @param string Ids -----------------------------------------非必传,IDS
 * @param uint32 AccountId -----------------------------------非必传,账户ID
 * @param string AccountIds ----------------------------------非必传,账户ID,支持多个
 * @param uint32 RoleId --------------------------------------非必传,角色ID
 * @param string RoleIds -------------------------------------非必传,角色ID,支持多个
 * @param uint32 Page ----------------------------------------非必传,页码
 * @param uint32 PageSize ------------------------------------非必传,单页条数
 * @return *pbAccount.AccountRoleListResponse, error
 * @author huwl
 */
func (e *AccountHandler) AccountRoleList(ctx context.Context, req *pbAccount.AccountRoleListRequest) (*pbAccount.AccountRoleListResponse, error) {
	params := map[string]interface{}{}
	if req.Id > 0 {
		params["id"] = req.Id
	}
	if req.Ids != "" {
		params["id IN (?)"] = strings.Split(strings.TrimRight(req.Ids, ","), ",")
	}
	if req.AccountId > 0 {
		params["account_id"] = req.AccountId
	}
	if req.AccountIds != "" {
		params["account_id IN (?)"] = tools.IntSplit(strings.TrimRight(req.AccountIds, ","), ",")
	}
	if req.RoleId > 0 {
		params["role_id"] = req.RoleId
	}
	if req.RoleIds != "" {
		params["role_id IN (?)"] = tools.IntSplit(strings.TrimRight(req.RoleIds, ","), ",")
	}
	if req.Page <= 0 {
		req.Page = 1
	}
	if req.PageSize == 0 {
		req.PageSize = 20
	}

	accountRoles := []models.AccountRole{}
	err := models.AccountRole{}.GetResultsByParams(&models.AccountRole{}, &accountRoles, params, int(req.Page), int(req.PageSize), "id desc")
	if err != nil {
		return nil, status.Errorf(codes.Aborted, err.Error())
	}

	accountRoleItems := []*pbAccount.AccountRole{}
	for _, accountRole := range accountRoles {
		accountRoleItems = append(accountRoleItems, &pbAccount.AccountRole{
			Id:         accountRole.Id,
			AccountId:  uint32(accountRole.AccountId),
			RoleId:     uint32(accountRole.RoleId),
			CreateTime: accountRole.CreateTime.Format("2006-01-02 15:04:05"),
		})
	}

	return &pbAccount.AccountRoleListResponse{
		AccountRoles: accountRoleItems,
		Page:         req.Page,
		PageSize:     req.PageSize,
	}, nil
}

/**
 * 保存分配角色
 *
 * @param uint32 AccountId -----------------------------------必传,账户ID
 * @param string RoleIds -------------------------------------必传,角色ID,支持多个
 * @return *pbResult.Result, error
 * @author huwl
 */
func (e *AccountHandler) SaveAssignRole(ctx context.Context, req *pbAccount.AssignRoleRequest) (*pbResult.Result, error) {
	if req.AccountId <= 0 {
		return nil, status.Errorf(codes.InvalidArgument, "账户ID错误")
	}
	if req.RoleIds == "" {
		return nil, status.Errorf(codes.InvalidArgument, "角色ID错误")
	}

	var total int64
	err := models.AccountRole{}.GetTotalByParams(&models.AccountRole{}, &total, map[string]interface{}{
		"account_id": req.AccountId,
	})
	if err != nil {
		return nil, status.Errorf(codes.Aborted, err.Error())
	}

	if total > 0 {
		i, err := models.AccountRole{}.DeleteByParams(&models.AccountRole{}, map[string]interface{}{
			"account_id": req.AccountId,
		})
		if err != nil {
			return nil, status.Errorf(codes.Aborted, err.Error())
		}
		if i < 0 {
			return nil, status.Errorf(codes.Aborted, err.Error())
		}
	}

	roleItemIds := strings.Split(req.RoleIds, ",")
	accountRoles := []models.AccountRole{}
	for _, value := range roleItemIds {
		roleId, _ := strconv.Atoi(value)
		accountRoles = append(accountRoles, models.AccountRole{
			AccountId: uint16(req.AccountId),
			RoleId:    uint16(roleId),
		})
	}

	i, err := models.AccountRole{}.Add(&accountRoles)
	if err != nil {
		return nil, status.Errorf(codes.Aborted, err.Error())
	}
	if i <= 0 {
		return nil, status.Errorf(codes.Aborted, "分配角色失败")
	}

	return &pbResult.Result{Code: 200, Msg: "分配角色成功"}, nil
}
